/* Copyright 2018-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
 * applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */
package com.github.drinkjava2.gosqlgo;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.github.drinkjava2.gosqlgo.util.ClassExistCacheUtils;
import com.github.drinkjava2.gosqlgo.util.GsgStrUtils; 

/**
 * DeployTool extract all SQL and Java in html or .js files to server side, and
 * reverse.
 * 
 * @author Yong Zhu
 * @since 1.0.0
 */
@SuppressWarnings("unchecked")
public class GoSqlGoEnv {
	public static final GoSqlGoEnv instance = new GoSqlGoEnv();

	protected String deployAbsolutePath;
	protected String deploy;
	protected String webappFolder;

	protected ServletTemplate javaTemplate;
	protected ServletTemplate qryTemplate;

	protected boolean isProduct = true;

	public GoSqlGoEnv() {
		InputStream is = DeployTool.class.getClassLoader().getResourceAsStream("GoSqlGo.properties");
		if (is == null)
			return;
		Properties prop = new Properties();
		try {
			prop.load(is);
			this.deploy = prop.getProperty("deploy");

			String stage = prop.getProperty("stage");
			if ("product".equals(stage))
				isProduct = true;
			else if ("develop".equals(stage))
				isProduct = false;
			else
				throw new IllegalArgumentException("In GoSqlGo.properties, stage can only be develop or production");

			String javaTemplateClassName = prop.getProperty("javaTemplateClass");
			if (GsgStrUtils.isEmpty(javaTemplateClassName))
				javaTemplateClassName = deploy + ".JavaTemplate";

			String qryTemplateClassName = prop.getProperty("qryTemplateClass");
			if (GsgStrUtils.isEmpty(qryTemplateClassName))
				qryTemplateClassName = deploy + ".QryTemplate";

			this.deployAbsolutePath = new File("").getAbsolutePath() + "/src/main/java/"
					+ GsgStrUtils.replace(deploy, ".", "/");
			this.webappFolder = new File("").getAbsolutePath() + "/src/main/webapp";

			Class<? extends ServletTemplate> javaTemplateClass = (Class<? extends ServletTemplate>) DeployTool.class.getClassLoader()
					.loadClass(javaTemplateClassName);
			this.javaTemplate = javaTemplateClass.newInstance();

			Class<? extends ServletTemplate> qryTemplateClass = (Class<? extends ServletTemplate>) DeployTool.class.getClassLoader()
					.loadClass(qryTemplateClassName);
			this.qryTemplate = qryTemplateClass.newInstance();

			return;
		} catch (Exception e) {
			throw new IllegalArgumentException(e);
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Return class stored in deploy package, if not found, return null
	 */
	public static Class<?> findStoredClass(String sqlJavaPiece) {
		if (sqlJavaPiece == null)
			return null;
		if (!GsgStrUtils.isLegalClassName(sqlJavaPiece))
			return null;
		return ClassExistCacheUtils.checkClassExist(
				new StringBuilder(GoSqlGoEnv.instance.getDeploy()).append(".").append(sqlJavaPiece).toString());
	}

	// ==========getter & setter =============

	public String getDeployAbsolutePath() {
		return deployAbsolutePath;
	}

	public void setDeployAbsolutePath(String deployAbsolutePath) {
		this.deployAbsolutePath = deployAbsolutePath;
	}

	public String getDeploy() {
		return deploy;
	}

	public void setDeploy(String deploy) {
		this.deploy = deploy;
	}

	public String getWebappFolder() {
		return webappFolder;
	}

	public void setWebappFolder(String webappFolder) {
		this.webappFolder = webappFolder;
	}

	public ServletTemplate getJavaTemplate() {
		return javaTemplate;
	}

	public void setJavaTemplate(ServletTemplate javaTemplate) {
		this.javaTemplate = javaTemplate;
	}

	public ServletTemplate getQryTemplate() {
		return qryTemplate;
	}

	public void setQryTemplate(ServletTemplate qryTemplate) {
		this.qryTemplate = qryTemplate;
	}

	public boolean isProduct() {
		return isProduct;
	}

	public void setProduct(boolean isProduct) {
		this.isProduct = isProduct;
	}

	public static GoSqlGoEnv getInstance() {
		return instance;
	}

}
